<template>
  <Page title="流程实例详情" description="查看流程实例的详细信息和执行历史">
    <div class="instance-detail">
      <Card title="基本信息" class="mb-4">
        <Descriptions :column="2" bordered>
          <DescriptionsItem label="流程实例ID">
            {{ instanceInfo?.id }}
          </DescriptionsItem>
          <DescriptionsItem label="流程名称">
            {{ instanceInfo?.processDefinitionName }}
          </DescriptionsItem>
          <DescriptionsItem label="流程版本">
            v{{ instanceInfo?.processDefinitionVersion }}
          </DescriptionsItem>
          <DescriptionsItem label="业务键">
            {{ instanceInfo?.businessKey || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="发起人">
            {{ instanceInfo?.startUserName || instanceInfo?.startUserId || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="状态">
            <Tag v-if="!instanceInfo?.ended && !instanceInfo?.suspended" color="processing">
              运行中
            </Tag>
            <Tag v-else-if="instanceInfo?.suspended" color="warning">
              已挂起
            </Tag>
            <Tag v-else-if="instanceInfo?.ended" color="success">
              已完成
            </Tag>
          </DescriptionsItem>
          <DescriptionsItem label="开始时间">
            {{ instanceInfo?.startTime }}
          </DescriptionsItem>
          <DescriptionsItem label="结束时间">
            {{ instanceInfo?.endTime || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="耗时" :span="2">
            {{ instanceInfo?.durationInMillis ? formatDuration(instanceInfo.durationInMillis) : '-' }}
          </DescriptionsItem>
        </Descriptions>
      </Card>

      <Card title="流程追踪" class="mb-4">
        <div class="diagram-container">
          <!-- 加载状态 -->
          <div v-if="diagramLoading" class="loading-wrapper">
            <Spin size="large" tip="正在加载流程图..." />
          </div>
          <!-- BPMN 查看器 -->
          <BpmnViewer
            v-else-if="bpmnXml"
            :bpmn-xml="bpmnXml"
            :highlighted-nodes="activeNodes"
            :finished-nodes="finishedNodes"
          />
          <!-- 空状态 -->
          <Empty v-else description="暂无流程图" />
        </div>
      </Card>

      <Card title="执行历史">
        <Timeline>
          <TimelineItem
            v-for="activity in historyList"
            :key="activity.id"
            :color="getActivityColor(activity)"
          >
            <div class="activity-item">
              <div class="activity-header">
                <span class="activity-name">{{ activity.activityName }}</span>
                <span class="activity-type">{{ activity.activityType }}</span>
              </div>
              <div class="activity-info">
                <span v-if="activity.assignee">办理人：{{ activity.assignee }}</span>
                <span>开始时间：{{ activity.startTime }}</span>
                <span v-if="activity.endTime">结束时间：{{ activity.endTime }}</span>
              </div>
            </div>
          </TimelineItem>
        </Timeline>
      </Card>
    </div>
  </Page>
</template>

<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';

import { Page } from '@vben/common-ui';

import {
  Card,
  Descriptions,
  Empty,
  Spin,
  Tag,
  Timeline,
  message,
} from 'ant-design-vue';

const DescriptionsItem = Descriptions.Item;
const TimelineItem = Timeline.Item;

import type { HistoricActivity, ProcessInstance } from '#/api/workflow';
import {
  getProcessInstanceDetailApi,
  getProcessInstanceDiagramApi,
  getProcessInstanceHistoryApi,
} from '#/api/workflow';

import BpmnViewer from '../components/bpmn-viewer/index.vue';

const route = useRoute();

const instanceId = ref<string>('');
const instanceInfo = ref<ProcessInstance>();
const historyList = ref<HistoricActivity[]>([]);

// 流程图相关
const diagramLoading = ref(false);
const bpmnXml = ref('');
const activeNodes = ref<string[]>([]);
const finishedNodes = ref<string[]>([]);

// 格式化耗时
function formatDuration(milliseconds: number): string {
  if (!milliseconds) return '-';

  const seconds = Math.floor(milliseconds / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) {
    return `${days}天${hours % 24}小时`;
  }
  if (hours > 0) {
    return `${hours}小时${minutes % 60}分钟`;
  }
  if (minutes > 0) {
    return `${minutes}分钟${seconds % 60}秒`;
  }
  return `${seconds}秒`;
}

// 获取活动颜色
function getActivityColor(activity: HistoricActivity): string {
  if (activity.endTime) {
    return 'green';
  }
  return 'blue';
}

// 加载实例信息
async function loadInstanceInfo() {
  try {
    const data = await getProcessInstanceDetailApi(instanceId.value);
    instanceInfo.value = data;
  } catch (error: any) {
    message.error(error?.msg || '加载实例信息失败');
  }
}

// 加载执行历史
async function loadHistory() {
  try {
    const data = await getProcessInstanceHistoryApi(instanceId.value);
    historyList.value = data;
  } catch (error: any) {
    message.error(error?.msg || '加载执行历史失败');
  }
}

// 加载流程图
async function loadDiagram() {
  diagramLoading.value = true;
  try {
    const data = await getProcessInstanceDiagramApi(instanceId.value);
    bpmnXml.value = data.bpmnXml;
    activeNodes.value = data.activeActivityIds || [];
    finishedNodes.value = data.finishedActivityIds || [];
  } catch (error: any) {
    message.error(error?.msg || '加载流程图失败');
  } finally {
    diagramLoading.value = false;
  }
}

// 初始化加载
onMounted(async () => {
  instanceId.value = route.params.id as string;
  if (!instanceId.value) {
    message.error('实例ID不能为空');
    return;
  }

  await Promise.all([loadInstanceInfo(), loadHistory(), loadDiagram()]);
});
</script>

<style scoped>
.instance-detail {
  padding: 16px;
}

.diagram-container {
  min-height: 600px;
  height: 70vh;
  max-height: 800px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fafafa;
  border-radius: 4px;
  overflow: hidden;
}

.diagram-container :deep(.bpmn-viewer) {
  height: 100%;
  width: 100%;
}

.loading-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.activity-item {
  padding: 8px 0;
}

.activity-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.activity-name {
  font-size: 14px;
  font-weight: 500;
}

.activity-type {
  font-size: 12px;
  color: #999;
}

.activity-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: #666;
}
</style>

